/*******************************************************************
 *
 * Copyright (C), 2021-2022, Letstrong, All rights reserved.
 *
 * Author      : 
 * Create Time : 2020-12-14
 * Version     : v0.1
 * Description : 
 *******************************************************************/

/*----------------------------Head file----------------------------*/

#include "rwip_config.h"

#if (BLE_OTA_SERVER)

#include "gap.h"
#include "gapc.h"
#include "gattc_task.h"
#include "attm.h"
#include "atts.h"
#include "co_utils.h"
#include "prf_utils.h"
#include "ota.h"
#include "ota_task.h"
#include "ota_protocol.h"

/*----------------------------macro file---------------------------*/
#define OTA_TASK_LOG_ENABLE		1

#if OTA_TASK_LOG_ENABLE
#include "log.h"
#define OTA_TASK_LOG			LOG_DEBUG
#else
#define OTA_TASK_LOG(...)
#endif

/*----------------------------type define--------------------------*/

/*----------------------------var define---------------------------*/

/*-------------------------func declaration------------------------*/

/*-----------------------------------------------------------------*/


static int gattc_write_req_ind_handler(ke_msg_id_t const msgid, struct gattc_write_req_ind const *param,
                                      ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
	uint8_t status = ATT_ERR_NO_ERROR;
	int msg_status = KE_MSG_CONSUMED;
	uint8_t conidx = KE_IDX_GET(src_id);

    // If the attribute has been found, status is ATT_ERR_NO_ERROR
    if(ke_state_get(dest_id) == OTA_IDLE)
    {		
        struct ota_env_tag* ota_env = PRF_ENV_GET(OTA, ota);
		if(param->handle == (ota_env->start_hdl + OTA_IDX_CTRL_POINT_NTF_CFG))
		{
			uint16_t ntf_cfg = co_read16p(&param->value[0]);
			OTA_TASK_LOG("OTA_IDX_CTRL_POINT_NTF_CFG = %d\r\n", ntf_cfg);
			if (ntf_cfg == PRF_CLI_START_NTF)
			{
				ota_env->ctrl_point_ntf_cfg[conidx] |= (OTA_NTF_SUP);	// Ntf cfg bit set to 1
			}
			else
			{
				ota_env->ctrl_point_ntf_cfg[conidx] &= ~(OTA_NTF_SUP);	// Ntf cfg bit set to 0
			}
		}
		else if(param->handle == (ota_env->start_hdl + OTA_IDX_PACKET_VAL))
		{
			otaProtocol_ProcessPacketDataEvt((uint8_t*)&param->value, param->length);
			//OTA_TASK_LOG("OTA_IDX_PACKET_VAL = %d\r\n", param->length);
		}
		else if(param->handle == (ota_env->start_hdl + OTA_IDX_CTRL_POINT_VAL))
		{
			otaProtocol_ProcessControlEvt((uint8_t*)&param->value, param->length);
			//OTA_TASK_LOG("OTA_IDX_CTRL_POINT_VAL = %d\r\n", param->length);
		}
			
		//Send write response
		struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm);
		//Send write response
		cfm->handle = param->handle;
		cfm->status = status;
	  	ke_msg_send(cfm);
    }
	else if(ke_state_get(dest_id) == OTA_BUSY)
    {
      	msg_status = KE_MSG_SAVED;
    }

    return (msg_status);
}   


static int gattc_read_req_ind_handler(ke_msg_id_t const msgid, struct gattc_read_req_ind const *param,
                                      ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
	uint8_t status = ATT_ERR_NO_ERROR;
	int msg_status = KE_MSG_CONSUMED;
	struct gattc_read_cfm * cfm;
	struct ota_env_tag* ota_env = PRF_ENV_GET(OTA, ota);
	uint16_t length = 0;
	uint8_t value[20] = {0};

	if(ke_state_get(dest_id) == OTA_IDLE)
	{
		if(param->handle == (ota_env->start_hdl + OTA_IDX_VERSION_VAL))
		{
			length = sizeof(uint16_t);
			uint16_t read_val = 0x0100;
			memcpy(value, (uint8_t*)&read_val, length);
		}
			
		cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, length);
		cfm->length = length;
		memcpy(cfm->value, value, length);
		cfm->handle = param->handle;
		cfm->status = status;
		
		// Send value to peer device.
      	ke_msg_send(cfm);	//read send cfm
	}
	else if(ke_state_get(dest_id) == OTA_BUSY)
	{
		msg_status = KE_MSG_SAVED;
	}

    return (msg_status);
}   


static int gattc_cmp_evt_handler(ke_msg_id_t const msgid,  struct gattc_cmp_evt const *param,
                                 ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
    /*if(param->operation == GATTC_NOTIFY)
    {
        //continue operation execution	
		//oads_exe_operation();
    }*/

    return (KE_MSG_CONSUMED);
}


/// Default State handlers definition
const struct ke_msg_handler ota_default_state[] =
{
    {GATTC_WRITE_REQ_IND,    	 (ke_msg_func_t) gattc_write_req_ind_handler},
    {GATTC_READ_REQ_IND,         (ke_msg_func_t) gattc_read_req_ind_handler},
    {GATTC_CMP_EVT,              (ke_msg_func_t) gattc_cmp_evt_handler},
};

/// Specifies the message handlers that are common to all states.
const struct ke_state_handler ota_default_handler = KE_STATE_HANDLER(ota_default_state);

#endif /* #if (BLE_OTA_SERVER) */
 
